﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using AntdUI;
using CodeGenerator.DBInfo;
using CodeGenerator.DBInfo.entity;
using CodeGenerator.Utils;
using MySql.Data.MySqlClient;
using Newtonsoft.Json.Linq;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
namespace CodeGenerator.Dialog
{
    public partial class ConnConfigDialog : Form
    {
        private Column[] ConnTableHeaders = { new Column("DBType", "数据库类型", ColumnAlign.Center), new Column("ConnName", "连接名称", ColumnAlign.Center) };
        AntList<dynamic> connList = new AntList<dynamic>();
        ConfigUtil Config { get; } = new ConfigUtil(ConfigUtil.ConnFile);
        JObject SelectedConn = null;
        #region 初始化        
        public ConnConfigDialog()
        {
            // 禁用大小可调整性
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
            // 禁用最大化按钮
            this.MaximizeBox = false;
            InitializeComponent();
        }
        private void ConnConfigDialog_Load(object sender, EventArgs e)
        {
            InitConnTable();
            InitDbSelection();
            InitRoleSelection();
        }
        /// <summary>
        /// 初始化连接列表
        /// </summary>
        private void InitConnTable()
        {
            connTable.Columns = ConnTableHeaders;
            ConnTableHeaders[0].Width = "80";
            connList.Clear();
            var configs = Config.GetConfigs();
            foreach (var connLink in configs)
            {
                connList.Add(connLink);
            }
            connTable.Binding(connList);
        }
        /// <summary>
        /// 初始化角色下拉框
        /// </summary>
        private void InitRoleSelection()
        {
            roleSelect.Items.Add("DEFAULT");
            roleSelect.Items.Add("SYSDBA");
            roleSelect.Items.Add("SYSOPER");
            roleSelect.SelectedIndex = 0;
        }
        /// <summary>
        /// 初始化数据类型下拉框
        /// </summary>
        private void InitDbSelection()
        {
            FieldInfo[] fields = typeof(DBType).GetFields();
            bool first = true;
            foreach (var field in fields)
            {
                if (!first)
                    dbSelect.Items.Add(field.Name);
                first = false;
            }
        }
        #endregion
        private void addConn_Click(object sender, EventArgs e)
        {
            if (dbSelect.Text.IsNullOrEmpty())
            {
                return;
            }
            dbSelect_SelectedIndexChanged(null, 0);
        }

        private void saveConn_Click(object sender, EventArgs e)
        {
            ConnectionInfo connInfo = GetConnectionInfo();
            if (SelectedConn == null)
            {
                int id = Config.AddConfig(connInfo);
                var json = Config.ToJsonObj(connInfo);
                json.Add("id", id);
                SelectedConn = json;
            }
            else
            {
                var json = Config.ToJsonObj(connInfo);
                json.Add("id", SelectedConn["id"]);
                Config.UpdateConfig(json);
            }
            InitConnTable();
            delConn.Enabled = true;
        }
        private ConnectionInfo GetConnectionInfo()
        {
            //校验数据库类型
            EnumHelper.ParseDbType(dbSelect.Text);
            return new ConnectionInfo()
            {
                DBType = dbSelect.Text,
                Host = host.Text,
                Port = uint.Parse(port.Text),
                UserName = userName.Text,
                Password = password.Text,
                ConnName = connName.Text,
                InitDb = initDb.Text.IsNullOrEmpty() ? null : initDb.Text,
                Privilege = roleSelect.Text == "DEFAULT" ? "" : roleSelect.Text
            };
        }
        private async void testConn_Click(object sender, EventArgs e)
        {
            if (dbSelect.Text.IsNullOrEmpty())
            {
                throw new Exception("请选择数据库类型");
            }
            ConnectionInfo connInfo = GetConnectionInfo();
            var getter = DBGetterFactory.GetDBGetter(EnumHelper.ParseDbType(dbSelect.Text), connInfo);
            testConn.Loading = true;
            await Task.Delay(500);
            try
            {
                getter.TestConnection();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                testConn.Loading = false;
            }
            AntdUI.Modal.open(new AntdUI.Modal.Config(this, "测试连接", "连接成功", TType.Success)
            {
                CancelText = null,
                OkText = "关闭"
            });
        }

        private void dbSelect_SelectedIndexChanged(object sender, int value)
        {
            var dbType = EnumHelper.ParseDbType(dbSelect.Text);
            SelectedConn = null;
            userName.Text = null;
            password.Text = null;
            initDb.Text = null;
            connName.Text = "localhost";
            addConn.Enabled = true;
            delConn.Enabled = false;
            switch (dbType)
            {
                case DBType.MySQL:
                    port.Text = "3306";
                    initDb.ReadOnly = true;
                    initDb.PlaceholderText = "无需填写";
                    initDBLabel.Text = "初始库";
                    roleSelect.Enabled = false;
                    roleSelect.SelectedIndex = -1;
                    break;
                case DBType.Oracle:
                    port.Text = "1521";
                    initDb.ReadOnly = true;
                    initDb.PlaceholderText = "";
                    initDb.ReadOnly = false;
                    initDBLabel.Text = "sid/name";
                    initDb.Text = "ORCL";
                    roleSelect.Enabled = true;
                    roleSelect.PlaceholderText = "DEFAULT";
                    roleSelect.SelectedIndex = 0;
                    break;
                case DBType.PostgreSQL:
                    port.Text = "5432";
                    initDb.ReadOnly = false;
                    initDb.PlaceholderText = "";
                    initDBLabel.Text = "初始库";
                    initDb.Text = "postgres";
                    roleSelect.SelectedIndex = -1;
                    roleSelect.Enabled = false;
                    break;
            }
        }

        private void connTable_DoubleClick(object sender, EventArgs e)
        {
            var tb = sender as Table;
            dynamic connInfo = connList[tb.SelectedIndex - 1];
            dbSelect.Text = connInfo["DBType"];
            dbSelect_SelectedIndexChanged(null, -1);
            SelectedConn = connInfo;
            host.Text = connInfo["Host"];
            port.Text = connInfo["Port"];
            userName.Text = connInfo["UserName"];
            password.Text = connInfo["Password"];
            initDb.Text = connInfo["InitDb"];
            connName.Text = connInfo["ConnName"];
            roleSelect.Text = connInfo["Privilege"];
            addConn.Enabled = true;
            delConn.Enabled = true;
        }

        private void delConn_Click(object sender, EventArgs e)
        {
            var result = AntdUI.Modal.open(new AntdUI.Modal.Config(this, "提示", $"是否删除该连接（{SelectedConn["DBType"]} - {SelectedConn["ConnName"]}）？", TType.Warn)
            {
                CancelText = "取消",
                OkText = "确定"
            });
            if (result == DialogResult.OK)
            {
                Config.RemoveConfig(SelectedConn);
                delConn.Enabled = false;
                dbSelect_SelectedIndexChanged(null, 0);
                InitConnTable();
            }
        }
    }
}
